import { BasePuzzleUtil } from './BasePuzzleUtil'
import type { ICanvas, IGrid, IText } from 'src/interfaces/IBook'
import { create_boxtext, leafer_position } from './LeaferUtil'
import {
  Group,
  Text,
  type IGroup,
  type IStroke,
  type IStrokePaint,
} from 'leafer-ui'
import _ from 'lodash'
export class CrosswordUtil extends BasePuzzleUtil {
  words: Record<string, string>
  answers: Record<string, [number, number][]>

  legend_type: IText

  across_group: IGroup
  down_group: IGroup

  // 记录 不同方向的数量
  across_num = 0
  down_num = 0

  constructor(
    canvas: ICanvas,
    title_model: IText,
    instruction_model: IText,
    words_grid_style: IGrid,

    words: Record<string, string>,
    answers: Record<string, [number, number][]>,
    legend_type: IText
  ) {
    super(canvas, title_model, instruction_model, [], words_grid_style)

    this.words = words
    this.answers = answers
    this.legend_type = legend_type
    this.across_group = new Group({
      x: 0,
      y: 0,
      editable: true,
      fill: '#FEB027',
      hitChildren: false,
    })
    this.down_group = this.across_group.clone() as IGroup

    this.topic_words_group = this.ans_words_group.clone() as IGroup
  }
  generate_puzzle = (): void => {
    // 清除画布的元素
    this.answer_frame.clear()
    this.topic_frame.clear()

    // 生成 标题和副标题
    this.dram_title(this.title_model, this.instruction_model)
    // 生成 words 区域
    this.generate_words()

    // 将 title groud 添加进 frame
    this.title_group.x = this.x_center_position(
      this.title_group.boxBounds.width,
      this.topic_frame.width as number
    )
    this.title_group.y = this.canvas.height * 0.03

    this.answer_frame.add(this.title_group)
    this.topic_frame.add(this.title_group.clone())

    // 设置 word and  topic groud 的坐标位置
    const words_grid_ceterX = this.x_center_position(
      this.ans_words_group.boxBounds.width,
      this.answer_frame.width as number
    )
    this.ans_words_group.x = words_grid_ceterX
    this.topic_words_group.x = words_grid_ceterX

    this.ans_words_group.y =
      this.title_group.boxBounds.height +
      this.canvas.height * 0.06 +
      this.words_grid_style.offet_y
    this.topic_words_group.y =
      this.title_group.boxBounds.height +
      this.canvas.height * 0.06 +
      this.words_grid_style.offet_y
    // 将组添加进 fram
    this.answer_frame.add(this.ans_words_group)
    this.topic_frame.add(this.topic_words_group)

    // 将 down 和 across 组添加进frame
    this.down_group.x = this.across_group.boxBounds.width + 100

    const down_across_group = new Group({
      x: 0,
      y:
        this.topic_words_group.y +
        this.topic_words_group.boxBounds.height +
        this.canvas.height * 0.06,
      editable: true,
      fill: '#FEB027',
      hitChildren: false,
    })
    down_across_group.add([this.across_group, this.down_group])
    down_across_group.x = this.x_center_position(
      down_across_group.boxBounds.width,
      this.answer_frame.width as number
    )

    this.answer_frame.add(down_across_group)
    this.topic_frame.add(down_across_group.clone())
  }

  generate_words = () => {
    // 遍历 answer
    let key_num = 1
    for (const key in this.answers) {
      const letter_indexs = this.answers[key] as [number, number][]
      for (let i = 0; i < key.length; i++) {
        // 获取字母
        const ltr_index = letter_indexs[i] as [number, number]

        // 获取实际渲染位置
        const [rx, ry] = leafer_position({
          x: ltr_index[0],
          y: ltr_index[1],
          width: this.words_grid_style.width,
          height: this.words_grid_style.width,
          stroke: this.words_grid_style.stroke as IStrokePaint,
          white_border: this.white_border,
          x_offet: this.words_grid_style.offet_x,
          y_offet: this.words_grid_style.offet_y,
          x_interval: this.words_grid_style.x_interval,
          y_interval: this.words_grid_style.y_interval,
        })

        // 创建 答案box
        const answer_box = create_boxtext({
          x: rx,
          y: ry,
          width: this.words_grid_style.width,
          height: this.words_grid_style.height,
          text: `${key[i]}`,
          text_style: this.words_grid_style.text as IText,
          stroke: this.words_grid_style.stroke as IStroke,
        })

        // 创建复制文字的类型
        const topic_text_style = _.cloneDeep(
          this.words_grid_style.text
        ) as IText
        topic_text_style.text_align = 'left'
        topic_text_style.vertical_align = 'top'
        topic_text_style.font.font_size *= 0.8
        // 创建 问题box
        const topic_box = create_boxtext({
          x: rx,
          y: ry,
          width: this.words_grid_style.width,
          height: this.words_grid_style.height,
          text: i == 0 ? `${key_num}` : '',
          text_style: topic_text_style,
          stroke: this.words_grid_style.stroke as IStroke,
        })

        this.topic_words_group.add(topic_box)
        this.ans_words_group.add(answer_box)
      }
      this.generate_across_down(key, letter_indexs, key_num)
      key_num += 1
    }
  }

  generate_across_down = (
    word: string,
    points: [number, number][],
    word_num: number
  ) => {
    // 获取 message
    const message = this.words[word]
    if (message === undefined) {
      return
    }
    // 计算方向
    if (points.length >= 2) {
      const point1 = points[0] as [number, number]
      const point2 = points[1] as [number, number]
      const is_down = Math.abs(point1[0] - point2[0]) < 1
      // 说明向下
      const [rx, ry] = leafer_position({
        x: 0,
        y: is_down ? this.down_num + 1 : this.across_num + 1,
        width: this.legend_type.font.font_size,
        height: this.legend_type.font.font_size,
        stroke: this.words_grid_style.stroke as IStrokePaint,
        white_border: this.white_border,
        x_offet: this.words_grid_style.offet_x,
        y_offet: this.words_grid_style.offet_y,
        x_interval: this.words_grid_style.x_interval,
        y_interval: this.legend_type.font.font_size * 0.5,
      })
      if (this.down_num == 0) {
        const title = new Text({
          x: 0,
          y: 0,
          fontSize: this.legend_type.font.font_size,
          fontFamily: this.legend_type.font.font_name,
          textAlign: 'left',
          verticalAlign: 'middle',
          fill: this.legend_type.font.font_color,
          text: `Down`,
        })
        this.down_group.add(title)
      } else {
        const title = new Text({
          x: 0,
          y: 0,
          fontSize: this.legend_type.font.font_size,
          fontFamily: this.legend_type.font.font_name,
          textAlign: 'left',
          verticalAlign: 'middle',
          fill: this.legend_type.font.font_color,
          text: `Across`,
        })
        this.across_group.add(title)
      }
      const text = new Text({
        x: rx,
        y: ry,
        fontSize: this.legend_type.font.font_size,
        fontFamily: this.legend_type.font.font_name,
        textAlign: 'left',
        verticalAlign: 'middle',
        fill: this.legend_type.font.font_color,
        text: `[${word_num}] ${message}`,
      })

      if (is_down) {
        this.down_num++
        this.down_group.add(text)
      } else {
        this.across_num++
        this.across_group.add(text)
      }
    }
  }
}
